package vfs.util;

import vfs.obj.entity.VFSNode;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Matthew Eavenson <durandal@uga.edu>
 */
public class VFSUtil {

    /*********************************************************************
     * Hashes the string input using the SHA1 algorithm.
     * @param   input	string to hash.
     * @return  SHA hash of the string.
     */
    public static String secureHash(String input) {
        StringBuilder output = new StringBuilder();
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(input.getBytes());
            byte[] digest = md.digest();
            for (int i = 0; i < digest.length; i++) {
                String hex = Integer.toHexString(digest[i]);
                if (hex.length() == 1) {
                    hex = "0" + hex;
                }
                hex = hex.substring(hex.length() - 2);
                output.append(hex);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return output.toString();
    }
    
    /***************************************************************
     * Render a Date object into a formatted string.
     * @param  d         Date to be formatted.
     * @return a String representation of the date encoded by this Calendar.
     */
    public static String formatDate(Date d){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(d);
    }
    
    public static VFSNode.PublicAccess getPublicAccess(String access){
        VFSNode.PublicAccess pa = null;
        if(access.equals("write")) pa = VFSNode.PublicAccess.WRITE;
        else if(access.equals("read")) pa = VFSNode.PublicAccess.READ;
        else pa = VFSNode.PublicAccess.NONE;
        return pa;
    }

    /***************************************************************
     * Return a list of String matches to an input String based on a
     * regular expression.
     * @param  input     An input String.
     * @param  regex     A regular expression String.
     * @param  groupNum  The group number to return.  See MatchResult for details.
     * @return a List of Strings which match the regular expression.
     */
    public static List<String> getMatches(String input, String regex, int groupNum) {
        List<String> matches = new ArrayList<String>();
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        MatchResult mr = null;
        while (m.find()) {
            mr = m.toMatchResult();
            matches.add(mr.group(groupNum));
        }
        return matches;
    }

    /***************************************************************
     * Return a single match to an input String based on a
     * regular expression.
     * @param  input     An input String.
     * @param  regex     A regular expression String.
     * @return the first String in the input that matches the regular expression.
     */
    public static String getMatch(String input, String regex) {
        String match = null;
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        MatchResult mr = null;
        m.find();
        mr = m.toMatchResult();
        match = mr.group(0);
        return match;
    }

    /*********************************************************************
     * Converts the contents of a File to a String.
     * @param   f	File to convert to a String
     * @return  contents of the specified File
     */
    public static String fileToString(File f) throws IOException {
        FileChannel fc = new FileInputStream(f).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate((int) fc.size());
        fc.read(buffer);
        fc.close();
        return new String(buffer.array());
    }

    /*********************************************************************
     * Converts the contents of a String to a File.
     * @param   s		String to convert to a File
     * @param   f		File that the String will be written to.
     * @param   append          append mode on the File.
     */
    public static void stringToFile(String s, File f, boolean append) throws IOException {
        if (f.getParentFile() != null && !f.getParentFile().exists()) {
            f.getParentFile().mkdirs();
        }
        FileChannel fc = new FileOutputStream(f, append).getChannel();
        byte[] b = s.getBytes();
        ByteBuffer buffer = ByteBuffer.wrap(b);
        fc.write(buffer);
        fc.close();
    }

    /*********************************************************************
     * Converts the contents of a String to a File.
     * @param   s	String to convert to a File
     * @param   f	File which the String will be written to.
     */
    public static void stringToFile(String s, File f) throws IOException {
        stringToFile(s, f, false);
    }
}
